<template>
  <el-card class="chart-card">
    <template #header>
      <span>{{ title }}</span>
    </template>
    
    <div v-if="!data || data.length === 0" style="padding: 50px; text-align: center">
      <el-empty :description="emptyText" />
    </div>
    <div v-else ref="chartRef" style="width: 100%; height: 300px"></div>
  </el-card>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, onUnmounted, watch, nextTick } from 'vue'
import * as echarts from 'echarts'

interface Props {
  title?: string
  data?: any[]
  type?: 'pie' | 'bar'
  colorMap?: Record<string, string>
  fieldNames?: {
    type: string
    value: string
  }
  emptyText?: string
  tooltipFormatter?: (params: any) => any
}

const props = withDefaults(defineProps<Props>(), {
  type: 'pie',
  fieldNames: () => ({ type: 'type', value: 'value' }),
  emptyText: '暂无数据'
})

const chartRef = ref<HTMLElement>()
let chartInstance: echarts.ECharts | null = null

// 处理数据
const processedData = computed(() => {
  if (!props.data || props.data.length === 0) return []
  
  return props.data
    .filter(item => item && (Number(item[props.fieldNames.value]) || 0) > 0) // 过滤掉值为0的项
    .map(item => ({
      name: item[props.fieldNames.type] || '未知',
      value: Number(item[props.fieldNames.value]) || 0,
      // 保留原始数据的所有字段，以便 tooltipFormatter 使用
      ...item
    }))
})

const initChart = () => {
  if (!chartRef.value) {
    return
  }
  
  if (!processedData.value.length) {
    return
  }
  
  if (chartInstance) {
    chartInstance.dispose()
    chartInstance = null
  }
  
  chartInstance = echarts.init(chartRef.value)
  
  let option: echarts.EChartsOption
  
  if (props.type === 'pie') {
    // 自定义 tooltip formatter
    const tooltipFormatter = props.tooltipFormatter 
      ? (params: any) => {
          // echarts pie chart params format: { dataIndex, data, value, name, ... }
          const formatted = props.tooltipFormatter!(params)
          return `${formatted.name}<br/>${formatted.value}`
        }
      : '{a} <br/>{b}: {c} ({d}%)'
    
    option = {
      tooltip: {
        trigger: 'item',
        formatter: tooltipFormatter
      },
      legend: {
        orient: 'horizontal',
        bottom: 0,
        data: processedData.value.map(item => item.name)
      },
      series: [
        {
          name: props.title,
          type: 'pie',
          radius: ['40%', '70%'],
          avoidLabelOverlap: false,
          itemStyle: {
            borderRadius: 10,
            borderColor: '#fff',
            borderWidth: 2
          },
          label: {
            show: true,
            formatter: '{b}: {c} ({d}%)'
          },
          emphasis: {
            label: {
              show: true,
              fontSize: 14,
              fontWeight: 'bold'
            }
          },
          data: processedData.value.map(item => ({
            name: item.name,
            value: item.value,
            // 保留所有原始字段以便 tooltipFormatter 访问
            ...Object.fromEntries(
              Object.entries(item).filter(([key]) => !['name', 'value'].includes(key))
            ),
            itemStyle: {
              color: props.colorMap?.[item.name]
            }
          }))
        }
      ],
      animation: true,
      animationDuration: 1000
    }
  } else {
    // 自定义 tooltip formatter for bar chart
    const tooltipFormatter = props.tooltipFormatter
      ? (params: any) => {
          // echarts bar chart params format: [{ name, value, data, ... }, ...]
          if (Array.isArray(params) && params.length > 0) {
            const param = params[0]
            const formatted = props.tooltipFormatter!(param)
            return `${formatted.name}<br/>${formatted.value}`
          } else if (params && !Array.isArray(params)) {
            const formatted = props.tooltipFormatter!(params)
            return `${formatted.name}<br/>${formatted.value}`
          }
          return `${params?.name || ''}<br/>${params?.value || 0}`
        }
      : undefined
    
    option = {
      tooltip: {
        trigger: 'axis',
        axisPointer: {
          type: 'shadow'
        },
        formatter: tooltipFormatter
      },
      grid: {
        left: '3%',
        right: '4%',
        bottom: '3%',
        containLabel: true
      },
      xAxis: {
        type: 'value'
      },
      yAxis: {
        type: 'category',
        data: processedData.value.map(item => item.name)
      },
      series: [
        {
          name: props.title,
          type: 'bar',
          data: processedData.value.map(item => ({
            value: item.value,
            // 保留所有原始字段以便 tooltipFormatter 访问
            ...Object.fromEntries(
              Object.entries(item).filter(([key]) => key !== 'value')
            ),
            itemStyle: {
              color: props.colorMap?.[item.name] || '#409EFF'
            }
          })),
          label: {
            show: true,
            position: 'right'
          }
        }
      ],
      animation: true,
      animationDuration: 1000
    }
  }
  
  chartInstance.setOption(option)
}

onMounted(() => {
  nextTick(() => {
    // 延迟初始化，确保 DOM 已完全渲染
    setTimeout(() => {
      initChart()
    }, 100)
    window.addEventListener('resize', handleResize)
  })
})

onUnmounted(() => {
  window.removeEventListener('resize', handleResize)
  if (chartInstance) {
    chartInstance.dispose()
    chartInstance = null
  }
})

watch(() => props.data, () => {
  nextTick(() => {
    setTimeout(() => {
      initChart()
    }, 150)
  })
}, { deep: true, immediate: false })

watch(() => props.type, () => {
  nextTick(() => {
    setTimeout(() => {
      initChart()
    }, 150)
  })
})

const handleResize = () => {
  chartInstance?.resize()
}
</script>

<style scoped lang="scss">
.chart-card {
  margin-bottom: 20px;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}
</style>

